Skip to content

NTQQ(Android) ​

教程验证状态

当前状态: 尚未确认本教程在近期版本上仍可用

已确认 QQ 版本: 暂无

最后确认时间: 暂无

如果你确认本教程在 Android 平台上依然可用,请打开 PR 或 issue 通知维护者,并注明 QQ 版本、Android 版本、设备架构,以及是否成功提取原始数据库和 key。

注意

如果运行脚本时出现问题,请尝试将所有文件中的所有libkernel替换为libbasic_share。

方法1(推荐) ​

说明

本方法不需要 root,只需要使用系统自带的备份功能导出 QQ 的数据即可。由于 QQ 限制,部分系统可能无法导出 QQ 数据,此时可以使用“聊天记录迁移”功能迁移到其他设备上。

经测试适用于9.0.65至9.1.60版本,更低版本可能无法使用此方法。

以下的md5函数返回结果均为 32 位,字符均为小写,在Python中等价于以下函数:def md5(s): i=__import__('hashlib').md5();i.update(s.encode('utf8'));return i.hexdigest() 为了方便起见,假设 QQ 号(表示为uin)为390251789,nt_uid为u_mIicAReWrdCB-kST6TXH7A。 一切以/data/user/0/com.tencent.mobileqq/开头的路径均表示root后可以访问到的绝对路径,若为处理备份文件,则此路径可能有所不同。

便捷获取 ​

计算 QQ_path_hash 和数据库密钥

获取nt_uid ​

获取nt_uid有多种方式,任意一种均可。

  • 将/data/user/0/com.tencent.mobileqq/databases/beacon_db_com.tencent.mobileqq文件作为纯文本文件打开,查找你的 QQ 号对应的uid,形式如"home_uin": "390251789","uid":"u_mIicAReWrdCB-kST6TXH7A",其中u_mIicAReWrdCB-kST6TXH7A即为nt_uid。 1
  • 在/data/user/0/com.tencent.mobileqq/files/uid/目录下,可见到文件名形如390251789###u_mIicAReWrdCB-kST6TXH7A的若干个文件,其中u_mIicAReWrdCB-kST6TXH7A即为nt_uid。 2
  • 若使用了QAuxiliary模块,可以通过打开[辅助功能]聊天和消息-[消息]转发消息点头像查看详细信息功能,合并转发由自己发送的消息,查看消息的senderUid属性获取,详见#32。 3

对nt_uid取md5即可得到QQ_UID_hash(即QQ_UID_hash = md5(nt_uid) = md5("u_mIicAReWrdCB-kST6TXH7A") = "255c42fc0f4d295678e6ff0135fcf5dd")

获取聊天记录文件 ​

聊天记录可在以下路径找到:

plain
/data/user/0/com.tencent.mobileqq/databases/nt_db/nt_qq_{QQ_path_hash}/nt_msg.db

此处的QQ_path_hash有两种方法获得:

  1. 猜测

    如果你登录的 QQ 账号数量不多,可以通过文件更新时间、文件大小等猜测。

  2. 计算

    对QQ_UID_hash进行如下运算即可得到QQ_path_hash:`QQ_path_hash = md5(md5(nt_uid) + "nt_kernel") = md5("255c42fc0f4d295678e6ff0135fcf5ddnt_kernel") = "b69bfb8e74137f4e4253d1af3e99493a"

    则聊天记录路径为/data/user/0/com.tencent.mobileqq/databases/nt_db/nt_qq_b69bfb8e74137f4e4253d1af3e99493a/nt_msg.db

获取密钥 ​

使用HxD或者其他二进制查看工具打开nt_msg.db文件,将文件头部跟随在QQ_NT DB后的可读字符串复制,形如6tPaJ9GP,记为rand。

此时可以计算出数据库密钥key:key = md5(QQ_UID_hash + rand) = md5("255c42fc0f4d295678e6ff0135fcf5dd6tPaJ9GP") = "71c0dfcef3b5ceae7c4a1c68ca662f4a"。

则数据库密钥为71c0dfcef3b5ceae7c4a1c68ca662f4a。

另外,文件头部还可能含有cipher_hmac_algorithm的值(如HMAC_SHA1)等与解密相关的信息,可被解析为Protobuf数据,详见#29 (comment),此处不展开说明。

转移到 Windows ​

取得数据库密钥后,请复制原始数据库文件和 key 到 Windows,再按统一解密处理。

如果文件头中出现HMAC_SHA1字样(示例),则将其作为cipher_hmac_algorithm的值。否则,可尝试HMAC_SHA512(默认值)或HMAC_SHA256。

方法2 ​

此方法要求您拥有手机的 root 权限。

若你想直接使用示例脚本

建议QQ版本为9.0.65或更低

基础环境 ​

以下环境配置任选一种即可。

Termux ​

首先,安装 Termux,换源并执行pkg up、termux-setup-storage

然后依次执行以下命令:

安装基础依赖:

shell
pkg in python wget tsu root-repo
pkg in frida frida-python

关闭 SELinux:

shell
su -c setenforce 0

接着,手动下载主版本相同的frida-server,解压到/data/local/tmp下,并重命名为friendly(不一定要完全一致,仅是建议文件名不包含frida以略微避免检测);

赋予friendly可执行权限后,新开一个终端以root权限运行friendly

下载 hook 脚本:

shell
wget https://raw.githubusercontent.com/QQBackup/qq-win-db-key/master/scripts/android/android_get_key.py

PC ​

你也可以在电脑端使用adb等来避免在手机端配置Termux。具体过程略。

获取密钥 ​

打开 QQ 并完成登录,进入主界面。将 QQ 切换到后台后继续下一步。

在 Termux 终端 / 电脑的终端 中运行:

shell
python android_get_key.py

也可手动指定版本号,但目前所有支持的版本号使用的脚本均相同。

shell
python android_get_key.py 8.9.58

此时应当输出Frida script injected.,若没有,请检查:

  • 是否以root权限运行frida-server
  • 是否以关闭 SELinux (即设置为宽容模式)
  • 是否已经关闭Magisk Hide与Shamiko,并且重启手机
  • frida-server与 Termux 中的frida版本号第一个点号前的数字是否相同
  • QQ 版本是否一致

接下来,可以确认命令行是否给出数据库密钥(以pKey显示)。

转移到 Windows ​

确认命令行输出 pKey 后,请复制原始数据库文件和 key 到 Windows,再按统一解密处理。

gpro 数据库密钥 ​

gpro_v1-6_{nt_uid}.db 位于与 nt_msg.db 相同的目录下:

plain
/data/user/0/com.tencent.mobileqq/databases/nt_db/nt_qq_{QQ_path_hash}/gpro_v1-6_{nt_uid}.db

注意

文件名中的 {nt_uid} 是 nt_uid 字符串(如 u_mIicAReWrdCB-kST6TXH7A),但密钥计算使用 QQ 号(uin),而非 nt_uid。

获取头部盐值 ​

使用 HxD 或其他二进制查看工具打开 gpro_v1-6_{nt_uid}.db,读取文件头部的前 16 个可读字符,记为 header(形如 vgdBdzWwwrNNGORk)。

计算密钥 ​

计算 gpro 数据库密钥

Python 参考实现
python
import hashlib

def get_gpro_key(uin: str | int, header_bytes: bytes) -> str:
    uin_bytes = str(uin).encode('utf-8')
    md5_uin   = hashlib.md5(uin_bytes).hexdigest()
    sha1_raw  = hashlib.sha1(uin_bytes).digest()
    md5_sha1  = hashlib.md5(sha1_raw).hexdigest()
    user_seed   = hashlib.md5((md5_uin + md5_sha1).encode()).hexdigest()
    header_seed = hashlib.md5(header_bytes).hexdigest()
    return hashlib.md5((header_seed + user_seed).encode()).hexdigest()

# 示例:
# get_gpro_key("1707889225", b"vgdBdzWwwrNNGORk")
# → "2a4e04f77fd4ab2f4a42717e3e69e3d3"

解密 ​

解密步骤与标准 NTQQ 数据库相同(参考统一解密),但注意以下参数差异:

参数标准数据库(nt_msg.db 等)gpro 数据库
自定义文件头1024 字节1024 字节
Page Size40964096
KDF Iterations40004000
KDF AlgorithmPBKDF2_HMAC_SHA512PBKDF2_HMAC_SHA512
HMAC AlgorithmHMAC_SHA1HMAC_SHA512

唯一差异在于 HMAC 算法:gpro 数据库固定使用 HMAC_SHA512,而非标准数据库的 HMAC_SHA1。使用解密工具时请注意手动指定此参数。

说明 ​

旧版文档曾提供在 Android 端直接导出明文数据库的方法。为保持流程一致并降低源设备上的改写风险,该方法不再作为当前教程步骤;请使用前面的方式提取原始数据库和 key,再在 Windows 上完成解密与转换。